<!-- 
 资源汇总 
 选项卡
 可编辑的表格
 -->
<template>
  <ContainerLayout class="resource-management">
    <div class="form-container">
      <div style="flex: 1; display: flex">
        <el-form ref="formRef" :inline="true" :model="queryForm" class="query-form" label-width="40px">
          <el-form-item label="部门" v-if="false">
            <el-cascader :options="deptList" :props="deptProps" style="width: 290px" v-model="queryForm.deptIds" collapse-tags clearable />
          </el-form-item>
          <el-form-item label="项目">
            <el-select v-model="projectValue" placeholder="请选择项目" style="width: 180px" :max-collapse-tags="1" multiple clearable collapse-tags>
              <template #header>
                <el-checkbox v-model="checkAllProject" :indeterminate="indeterminateProject" @change="handleCheckAllProject">全部</el-checkbox>
              </template>
              <el-option v-for="item in projectList" :key="item.code" :label="`${item.code}-${item.cname}`" :value="item.id" />
            </el-select>
          </el-form-item>

          <TimeSlotDatePicker label="时段" v-model="queryForm.date" />

          <el-form-item>
            <el-button type="primary" @click="handleClickBtnSubmit" :icon="Search">查询</el-button>
            <el-button @click="handleClickBtnReset" :icon="Refresh">重置</el-button>
          </el-form-item>
        </el-form>
      </div>
      <el-button :type="!isMultiple ? 'default' : 'primary'" @click="handleClickChkMultiple" :icon="!isMultiple ? CircleCheck : CircleCheckFilled">多单元格操作</el-button>
      <el-button :type="!isMultiple ? 'info' : 'primary'" :icon="EditPen" :disabled="!isMultiple" @click="handleClickBtnEditMultiple">批量编辑</el-button>
    </div>
    <div class="table-container" ref="tableContainer">
      <el-scrollbar :height="scrollbarHeight" always>
        <el-space direction="vertical" :fill="true" :size="20" style="width: 100%">
          <div v-for="tableItem in tableList" class="table-cells">
            <div class="table-title">{{ tableItem.tableTitle }}</div>
            <div class="table-wrap" ref="tableWrap">
              <el-table ref="dataTable" :data="tableItem.tableData" :height="tableItem.height" :style="dataTableStyle" border scrollbar-always-on show-summary :summary-method="getSummaries" header-cell-class-name="table-header-row" empty-text="没有数据">
                <el-table-column prop="parentDeptName" label="地区" width="120" fixed />
                <el-table-column label="部门" width="150" fixed>
                  <template #default="scope">
                    <div>{{ scope.row.deptName }}({{ scope.row.deptUserLength }})</div>
                  </template>
                </el-table-column>
                <el-table-column v-for="(item, index) in tableColumnDate" :prop="item.label" :key="index" width="70" resizable>
                  <template #header>
                    <div class="table-header-cell">
                      <div>{{ item.label }}</div>
                    </div>
                  </template>
                  <template #default="scope">
                    <div v-if="tableItem.project.isTotal">{{ scope.row[item.columnName] }}</div>
                    <template v-else>
                      <el-tag v-if="!isMultiple" :type="scope.row[item.columnName] == 0 ? 'danger' : 'info'" class="table-cell" @click="handleClickTableCol(scope.row, tableItem.project, item.columnName)">{{ scope.row[item.columnName] }}</el-tag>
                      <div v-else :class="{ 'table-cell-checked': scope.row[item.columnName + '|checked'] }">
                        <el-tag :type="scope.row[item.columnName] == 0 ? 'danger' : 'info'" class="table-cell" @click="handleClickTableCol(scope.row, tableItem.project, item.columnName)">{{ scope.row[item.columnName] }}</el-tag>
                      </div>
                    </template>
                  </template>
                </el-table-column>
                <el-table-column></el-table-column>
              </el-table>
            </div>
          </div>
        </el-space>
      </el-scrollbar>
    </div>
  </ContainerLayout>
  <DialogUpdateHeadcountByProject ref="dialogUpdateHeadcountByProjectRef" @submited="handlerDialogUpdateSubmited" />
  <DialogUpdateHeadcountByProjectMultiple ref="dialogUpdateHeadcountByProjectMultipleRef" @submited="handlerDialogUpdateSubmited" />
</template>
<script lang="ts" setup>
import ContainerLayout from '../layout/ContainerLayout.vue'
import DialogUpdateHeadcountByProject from '../components/dialog/DialogUpdateHeadcountByProject.vue'
import DialogUpdateHeadcountByProjectMultiple from '../components/dialog/DialogUpdateHeadcountByProjectMultiple.vue'
import { reactive, ref, onMounted, h, nextTick } from 'vue'
import { useDeptStore, useProjectssStore } from '../stores'
// import IProjectTypes from '../interface/IProjectTypes'
import type { CheckboxValueType } from 'element-plus'
import { Refresh, Search, CircleCheck, CircleCheckFilled, EditPen } from '@element-plus/icons-vue'
import * as utils from '../utils'
import http from '../http'
import TimeSlotDatePicker from '../layout/FormTableLayout/TimeSlotDatePicker.vue'
import Api from '../api'
import { ElMessage } from 'element-plus'

const deptCountMap = ref<any>({})
const tableWrap = ref<HTMLElement | null>(null)
// 弹窗
const dialogUpdateHeadcountByProjectRef = ref<InstanceType<typeof DialogUpdateHeadcountByProject>>()
const dialogUpdateHeadcountByProjectMultipleRef = ref<InstanceType<typeof DialogUpdateHeadcountByProjectMultiple>>()

const projectssStore = useProjectssStore()
const deptStore = useDeptStore()
const deptList = ref(deptStore.getAllState())
const deptProps = ref({ multiple: true, label: 'deptName', value: 'deptId' })
// const projectTypes = ref<IProjectTypes[]>(useTaskTypeStore().getAllState())
// 多选
const checkAllProject = ref(false)
const indeterminateProject = ref(false)
const projectValue = ref<CheckboxValueType[]>([])
// 项目列表
const projectList = ref<Array<{ id: number; code: string; cname: string }>>(projectssStore.getAllState() as any)
// 表格是否查询过
const isQueryed = ref(false)
const projectTitle = ref<string>('')
const tableColumnDate = ref<any[]>([])
const dataTableStyle = ref({})
// 表格列表
const tableList = ref<{ tableTitle: string; project: any; tableData: any[]; height: any }[]>([])
// 表格数据
const tableRows = ref<any[]>([])
const tableContainer = ref(ref<HTMLElement | null>(null))
const scrollbarHeight = ref(400)
const weeks = ref()
// 表单
const queryForm = reactive({
  user: '',
  projectId: '',
  date: [] as Date[],
  deptIds: [] as string[] | number[],
})
// 是多选模式
const isMultiple = ref(false)

/**
 * 处理全选项目的逻辑
 *
 * @param val Checkbox 的值
 */
const handleCheckAllProject = (val: CheckboxValueType) => {
  indeterminateProject.value = false
  if (val) {
    projectValue.value = projectList.value.map((_) => _.id)
  } else {
    projectValue.value = []
  }
}
/**
 * 点击表格列时触发的函数
 *
 * @param row 行数据
 * @param project 项目数据
 */
const handleClickTableCol = (row: any, project: any, columnName: any) => {
  if (isMultiple.value) {
    // 多单元格编辑模式
    if (row[columnName] != 0) {
      row[columnName + '|checked'] = !row[columnName + '|checked']
    }
    // checkedColumns.value.push(`${row.deptId} - ${columnName}`)
    // console.log(checkedColumns.value)
    // resultItem[key + '|checked'] = false
  } else {
    // 点击单元格
    const { deptId, deptName } = row
    const { id, name, cname } = project

    const weekStartDate = new Date(columnName.split(' - ')[0])
    let weekEndDate = utils.formatDate(queryForm.date[1], 'yyyy-MM-dd')
    if (row[columnName + '|flag']) {
      weekEndDate = utils.formatDate(new Date(columnName.split(' - ')[1]))
    }
    // console.log('row', row)
    dialogUpdateHeadcountByProjectRef.value?.openDialog({
      weekStartDate,
      weekEndDate,
      deptId,
      deptName,
      projectId: id,
      projectCode: name,
      projectName: cname,
      userNum: row[columnName],
      flag: row[columnName + '|flag'],
      colId: row[columnName + '|id'],
    })
  }
}

const handlerDialogUpdateSubmited = async () => {
  await handleClickBtnSubmit()
  isMultiple.value = false
}
/**
 * 提交表单处理函数
 *
 * @returns {Promise<void>} 返回一个异步操作的Promise对象，无返回值
 */
const handleClickBtnSubmit = async () => {
  // console.log('queryForm', queryForm)
  isQueryed.value = true
  projectTitle.value = ''

  if (queryForm.date.length == 2) {
    const [start, end] = queryForm.date
    weeks.value = utils.getWeeksBetweenDates(start, end)

    await setTableColumn()
    await getDeptList()
    tableList.value = []
    nextTick(async () => {
      await buildDataTable()
    })
  }
}

/**
 * 异步构建数据表格。
 *
 * @returns 无返回值。
 */
const buildDataTable = async () => {
  // console.log(JSON.stringify(tableRows.value))
  // console.log(JSON.stringify(tableColumnDate.value))

  const rowsResult = await getRequirementList()

  // console.log('tableColumnDate.value', tableColumnDate.value)
  // console.log('rowsResult', rowsResult)
  const tableData = await mergeData(tableRows.value, tableColumnDate.value)
  // console.log('tableData', tableData)

  // 获取选中的项目列表项目列表
  const items = projectList.value.filter((e: any) => {
    if (projectValue.value.includes(e.id)) {
      return e
    }
  })
  // console.log('items', projectValue.value)

  tableList.value = items.map((item: any) => {
    // console.log('item', item.id)
    // console.log('rowsResult', rowsResult)
    const rows = rowsResult.filter((e: any) => e.projectId == item.id)
    const newData = mergeLists(tableData, rows)
    // console.log('rows 224', rows.filter((e: any) => e.deptId == 224))
    let height = (newData.length + 1) * 43 + 100
    if (height > 800) {
      height = 800
    }

    newData.map(async (e: any) => {
      e.deptUserLength = deptCountMap.value[e.deptId]
      e.checked = false
    })

    return {
      tableTitle: `${item.code}-${item.cname}`,
      height,
      project: { ...item },
      tableData: newData,
    }
  })
  if (items.length > 0) {
    // // Remaining/Available 实际差额
    // tableList.value.push({
    //   tableTitle: 'Remaining/Available 实际差额',
    //   project: {
    //     isTotal: true,
    //   },
    //   tableData,
    // })

    // // Total Requirement 所有项目需求
    // await getTotalRequirement(tableData)

    // Total Headcount 人事总人数
    await getTotalHeadcount(tableData)
    await tableColumnColspan()
  }
}

const tableColumnColspan = () => {
  // setTimeout(() => {
  //   const tableWrapElement = tableContainer.value
  //   if (tableWrapElement) {
  //     // 表格的最后一行前两个单元格合并
  //     const tableFooters = tableWrapElement.querySelectorAll('.el-table__footer')
  //     tableFooters.forEach((e: any) => {
  //       const tds = e.querySelectorAll('td')
  //       const tbs0 = tds[0] as HTMLElement
  //       tbs0.setAttribute('colspan', '2')
  //       tbs0.style.textAlign = 'center'
  //       tds[1].remove()
  //     })
  //   }
  // }, 200)
}
/**
 * 合并两个列表
 *
 * @param list1 第一个列表
 * @param list2 第二个列表
 * @returns 合并后的列表
 */
const mergeLists = (list1: any, list2: any) => {
  return list1.map((item1: any) => {
    const matchingItems = list2.filter((item2: any) => item2.deptId === item1.deptId)
    const resultItem = { ...item1 }
    matchingItems.forEach((item2: any) => {
      const key = `${item2.weekStartDate} - ${item2.weekEndDate}`
      resultItem[key] = item2.weekUserNum
      resultItem[item2.weekStartDate] = item2.weekUserNum
      resultItem[item2.weekEndDate] = item2.weekUserNum
      resultItem[key + '|flag'] = item2.weekUserNum >= 0 ? true : false
      resultItem[key + '|id'] = item2.id
      resultItem[key + '|checked'] = false
    })
    return resultItem
  })
}

/**
 * 计算表格数据中的汇总信息
 *
 * @param param 包含表格列信息和数据的对象
 * @returns 返回汇总信息的数组，每个元素可能是字符串或VNode，表示该列的汇总结果
 */
const getSummaries = (param: any) => {
  const { columns, data } = param
  const sums: any[] = []
  columns.forEach((column: any, index: number) => {
    if (index === 0) {
      sums[index] = h('div', { class: 'total-headcount', style: 'width:270px;' }, ['Total Headcount'])
      return
    }
    const values = data.map((item: any) => Number(item[column.property]))
    // sums[index] = '0'
    if (!values.every((value: any) => Number.isNaN(value))) {
      sums[index] = values.reduce((prev: any, curr: any) => {
        const value = Number(curr)
        if (!Number.isNaN(value)) {
          return prev + curr
        } else {
          return prev
        }
      }, 0)
    } else {
      // console.log(index)
      sums[index] = ''
    }
  })
  sums[1] = ''
  return sums
}

/**
 * 合并数据函数
 *
 * @param a 第一个数据集合，包含多个部门对象
 * @param b 第二个数据集合，包含多个时间区间对象
 * @returns 合并后的数据集合，包含合并后的部门对象数组
 */
const mergeData = (a: any, b: any) => {
  // console.log('b', b)
  // console.log('tableColumnDate.value', tableColumnDate.value)
  const result: any[] = []
  // 遍历集合a中的每个部门对象
  a.forEach((department: any) => {
    const mergedObj = { ...department }
    // 遍历集合b中的每个时间区间对象
    b.forEach((timeRange: any) => {
      const { columnName, start, end } = timeRange
      // 将时间区间相关的属性添加到合并后的对象中，并初始化为0
      mergedObj[columnName] = 0
      mergedObj[start] = 0
      mergedObj[end] = 0
    })
    result.push(mergedObj)
  })
  return result
}
/**
 * 点击按钮重置表单
 *
 * 异步调用 resetForm 函数重置表单
 */
const handleClickBtnReset = async () => {
  await resetForm()
}

/**
 * 重置表单
 *
 * 重置查询表单的所有字段到初始状态，包括用户、项目ID、日期范围、部门ID数组和时间日志类别
 */
const resetForm = () => {
  isQueryed.value = false
  projectTitle.value = ''
  const [start, end] = utils.getDateRangeByDate(utils.shortcutsType.本月) as Date[]
  queryForm.user = ''
  queryForm.projectId = ''
  queryForm.date = [start, end]
  queryForm.deptIds = [] as string[] | number[]
  projectValue.value = []
  handleClickBtnSubmit()
}
/**
 * Total Headcount 人事总人数
 *
 * @returns 无返回值
 */
const getTotalHeadcount = async (tableData: any) => {
  const rowsAll = await getRequirementList('listall')
  const newDataAll = mergeLists(tableData, rowsAll)

  let height = (newDataAll.length + 1) * 43 + 100
  if (height > 800) {
    height = 800
  }

  newDataAll.map(async (e: any) => {
    e.deptUserLength = deptCountMap.value[e.deptId]
  })

  tableList.value.push({
    tableTitle: '所有项目需求',
    height,
    project: {
      isTotal: true,
    },
    tableData: newDataAll,
  })
}

/**
 * 获取部门列表
 *
 * @returns 返回处理后的部门列表
 */
const getDeptList = async () => {
  const data = deptStore.getAllListState()
  const deptMap = new Map()
  const result: any = []

  // 先将所有部门信息存入Map，方便后续查找父部门名称
  data.forEach((item: any) => {
    deptMap.set(item.deptId, item)
  })

  data.forEach((item: any) => {
    const { deptId, parentId, deptName } = item
    const deptNamesExclude = '总经办,技术组'.split(',')
    if (parentId !== 100 && deptId !== 100 && deptNamesExclude.indexOf(deptName) === -1) {
      const parentItem = deptMap.get(parentId)
      const parentDeptName = parentItem.deptName
      result.push({ ...item, parentDeptName })
    }
  })

  tableRows.value = result
}
/**
 * 异步获取数据
 *
 * @returns 返回数据行
 */
const getRequirementList = async (type: 'list' | 'listall' = 'list') => {
  const rows = await httpGetDataRow({
    path: `/dev-api/oa/requirement/${type}`,
  })
  return rows
}
const httpGetDataRow = async (queryParams: any) => {
  const [first] = weeks.value
  const [last] = weeks.value.slice(-1)
  const startTimelogDate = utils.formatDate(first.start, 'yyyy-MM-dd')
  const endTimelogDate = utils.formatDate(last.end, 'yyyy-MM-dd')
  const defaultParams = {
    method: 'GET',
    path: ``,
    params: { pageSize: 99999, startTimelogDate, endTimelogDate },
  }
  Object.assign(defaultParams, queryParams)
  const res = await http(defaultParams)
  return res.rows
}
/**
 * 设置表格列
 *
 * @returns 无返回值
 */
const setTableColumn = async () => {
  // 设置 table 列
  tableColumnDate.value = []
  await new Promise((resolve) =>
    setTimeout(() => {
      tableColumnDate.value = [
        ...weeks.value.map((e: any) => {
          const start = utils.formatDate(e.start, 'yyyy-MM-dd')
          // console.log('start', start)
          const end = utils.formatDate(e.end, 'yyyy-MM-dd')
          const startYear = utils.formatDate(e.start, 'yyyy')
          const endYear = utils.formatDate(e.end, 'yyyy')
          const startDay = utils.formatDate(e.start, 'MM-dd')
          const endDay = utils.formatDate(e.end, 'MM-dd')
          return { label: start, columnName: `${start} - ${end}`, start, end, startDay, endDay, startYear, endYear }
        }),
      ]
      resolve(true)
    }, 0)
  )
}
/**
 * 处理点击切换是否允许多选状态的方法
 *
 * @returns 无返回值
 */
const handleClickChkMultiple = () => {
  tableList.value.map((el) => {
    el.tableData.map((e: any) => {
      tableColumnDate.value.map((item: any) => {
        e[item.columnName + '|checked'] = false
      })
    })
  })
  isMultiple.value = !isMultiple.value
}

// 批量编辑
const handleClickBtnEditMultiple = () => {
  // row[columnName + '|id']
  const editColumns: any[] = []

  tableList.value.map((el) => {
    el.tableData.map((e: any) => {
      tableColumnDate.value.map((item: any) => {
        if (e[item.columnName + '|checked']) {
          editColumns.push({
            id: e[item.columnName + '|id'],
            projectName: el.tableTitle,
            columnName: item.columnName,
            parentDeptName: e.parentDeptName,
            deptName: e.deptName,
          })
        }
      })
    })
  })
  if (editColumns.length == 0) {
    ElMessage.warning('请选择要编辑的单元格！')
  }
  dialogUpdateHeadcountByProjectMultipleRef.value?.openDialog(editColumns)
}

onMounted(async () => {
  deptCountMap.value = await Api.Dept.getDeptUserCountMap()
  await handleClickBtnReset()
  // console.log('projectList', queryForm.date)
  if (tableContainer.value) {
    scrollbarHeight.value = tableContainer.value.offsetHeight
    dataTableStyle.value = { width: tableContainer.value.offsetWidth + 'px' }
  }
  // dataTableStyle
})
</script>
<style lang="scss" scoped>
.resource-management {
  display: flex;
  flex-direction: column;
  .form-container {
    display: flex;
    justify-content: flex-start;
  }
  .table-container {
    flex: 1;
    display: flex;
    flex-direction: column;
    .table-wrap {
      flex: 1;
      width: 100%;
      overflow: hidden;
    }
  }
  .table-header-cell {
    writing-mode: vertical-lr;
    // line-height: 1;
  }
  .table-cell {
    cursor: pointer;
    width: 100%;
  }
  .table-cells {
    width: 100%;
    overflow: hidden;
  }
  .table-cell-checked {
    position: relative;
    &::after {
      content: '';
      display: block;
      position: absolute;
      z-index: 99;
      width: 10px;
      height: 10px;
      background-color: aquamarine;
      bottom: 0;
      left: 0;
    }
  }
}
</style>
